/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "FLIP对外接口.h"

#include "C_物理管理/S_PhysicsFLIP.h"
#include <ppl.h>



S_Physics* f_创建FLIP物理引擎(vec3 域大小) {
	S_PhysicsFLIP* phy = new S_PhysicsFLIP();
	phy->m_Core = f_flip_创建流体单元(64, 0.5, 0.1, 1.0f / 60.0f);
	//phy->m_Core = f_flip_创建流体单元(64, 0.01, 0.8, 1.0f / 60.0f);
	phy->m_Core->m_域属性.m_单元属性.m_世界大小 = 域大小;
	phy->m_Core->m_域属性.m_单元属性.m_域世界偏移 = { 0,0,0 };


	return phy;
}

void f_销毁FLIP物理引擎(S_Physics* phy) {
	f_flip_销毁流体单元(((S_PhysicsFLIP*)phy)->m_Core);
	delete phy;
}



uint32 f_FLIP_get解算器域分辨率(S_Physics* phy, uint8 层级) {
	S_PhysicsFLIP* flip = dynamic_cast<S_PhysicsFLIP*>(phy);

	return flip->m_Core->m_域属性.m_单元属性.m_分辨率.x;
}

void f_FLIP_set解算器域分辨率(S_Physics* phy, uint8 层级) {
	S_PhysicsFLIP* flip = dynamic_cast<S_PhysicsFLIP*>(phy);
	//flip->m_Core->m_域属性.m_分辨率 = { 分辨率 ,分辨率 ,分辨率 };

	f_flip_分配单元(flip->m_Core);
}

S_物理几何体* f_FLIP平面几何体(const vec4& v) {
	
	return nullptr;
}

S_物理几何体* f_FLIP长方体几何体(const vec3& v) {
	
	return 0;
}
S_物理几何体* f_FLIP球体几何体(const float32 半径) {
	
	return nullptr;
}
S_物理几何体* f_FLIP凸壳几何体(const S_三角Mesh mesh) {
	
	return 0;
}

S_物理几何体* f_FLIP网格几何体(const S_三角Mesh mesh) {
	
	return nullptr;
}


S_物理体* f_FLIP刚体(S_物理几何体& geom, S_物理材质& mat) {
	
	return 0;
}
S_物理体* f_FLIP静态(S_物理几何体& geom, S_物理材质& mat) {
	
	return 0;
}

S_物理体* f_FLIP控制(S_物理几何体& geom, S_物理材质& mat) {
	
	return nullptr;
}

S_物理体* f_FLIP创建车(S_Physics* 解算器, S_车体参数& 车体参数) {
	
	return nullptr;
}

S_物理体* f_FLIP创建流体(S_Physics* 解算器, S_物理几何体& geom, S_物理材质& mat, const S_Tranform& t) {
	S_物理体* body = new S_物理体();

	body->m_Type = E_物理体类型::E_物理体_流体;
	body->m_Data = f_flip创建流体body();

	return body;
}

车辆容器_t f_getFLIP车辆(S_Physics* 解算器) {
	车辆容器_t car;
	
	return car;
}

bool f_FLIP_切换物理体类型(S_物理体* body, E_物理体类型 类型) {
	switch (类型)
	{
	case E_物理体类型::E_物理体_流体: {
		if (body->m_Data) {
			if (body->m_Type == 类型) {
				return false;
			}
			free(body->m_Data);
		}
		body->m_Data = f_flip创建流体body();
		
		break;
	}
	default:
		break;
	}

	body->m_Type = 类型;
}

void f_FLIP发射流体(S_Physics* 解算器, std::vector<S_物理体*>& bodys) {
	S_PhysicsFLIP* phy = (S_PhysicsFLIP*)解算器;

	S_FLIP流体* 发射器 = (S_FLIP流体*)bodys[0]->m_Data;
	//phy->
	//vec3 offset = 发射器->m_Loc - phy->m_Core->m_域世界偏移;
	uvec3 dim = phy->m_Core->m_域属性.m_单元属性.m_分辨率;
	uint32 层 = phy->m_Core->m_域属性.m_单元属性.m_分辨率.x * phy->m_Core->m_域属性.m_单元属性.m_分辨率.y;
	

	/*for (uint32 z = 0; z < dim.z; ++z) {
		for (uint32 y = 0; y < dim.y; ++y) {
			for (uint32 x = 0; x < dim.x; ++x) {
				uint64 index = 层 * z + dim.x * y + x;
				if (phy->m_Core->m_域属性.m_Mask[index]) {
					phy->m_Core->m_方向[index] = 发射器->m_发射方向;
					phy->m_Core->m_密度[index] = 发射器->m_密度;
				}
			}
		}
	}*/

	Concurrency::parallel_for<uint32>(0, dim.z, [&](uint32 z) {
		for (uint32 y = 0; y < dim.y; ++y) {
			for (uint32 x = 0; x < dim.x; ++x) {
				uint64 index = 层 * z + dim.x * y + x;
				if (phy->m_Core->m_域属性.m_Mask[index]) {
					//phy->m_Core->m_方向[index] = 发射器->m_发射方向;
					phy->m_Core->m_方向X[index] = 发射器->m_发射方向.x;
					phy->m_Core->m_方向Y[index] = 发射器->m_发射方向.y;
					phy->m_Core->m_方向Z[index] = 发射器->m_发射方向.z;

					phy->m_Core->m_密度[index] = 发射器->m_密度;
				}
			}
		}

	});
	//phy->m_Core->m_Mask;

}

//btHinge2Constraint

S_域区* f_FLIP_get域属性(S_Physics* 解算器) {
	S_PhysicsFLIP* phy = (S_PhysicsFLIP*)解算器;
	return &phy->m_Core->m_域属性;
}

S_体素* f_FLIP_get物体体素(S_物理体* body) {
	switch (body->m_Type) {
	case E_物理体类型::E_物理体_流体: return ((S_FLIP流体*)body->m_Data)->m_体素;
	//case E_物理体类型::E_物理体_刚体 : return ((S_FLIP刚体*)body->m_Data)->m_体素;
	}
	
	return nullptr;
}




void f_FLIP_模拟(S_Physics* 解算器) {

}




void f_FLIP流体数据写入到顶点缓存(S_Physics* 解算器, S_FLIP可视数据* data) {
	S_PhysicsFLIP* phy = (S_PhysicsFLIP*)解算器;
	auto* core = phy->m_Core;


	const uvec3& 分辨率 = core->m_域属性.m_单元属性.m_分辨率;

	
	const uvec3 dim = { 分辨率.x, 分辨率.y , 分辨率.z };
	for (uint32 z = 0; z < dim.z; ++z) {
		for (uint32 y = 0; y < dim.y; ++y) {
			for (uint32 x = 0; x < dim.x; ++x) {
				uint64 id = f_坐标转线性索引({ x,y,z }, dim);

				if (core->m_域属性.m_Mask[id]) {
					data[id].密度 = 2.0;
				}
				else {
					data[id].密度 = core->m_密度[id];
				}
				
			}
		}
	}
}








